package com.hm.gateway;

import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.web.ErrorProperties;
import org.springframework.boot.autoconfigure.web.WebProperties.Resources;
import org.springframework.boot.autoconfigure.web.reactive.error.DefaultErrorWebExceptionHandler;
import org.springframework.boot.web.error.ErrorAttributeOptions;
import org.springframework.boot.web.reactive.error.ErrorAttributes;
import org.springframework.context.ApplicationContext;
import org.springframework.http.HttpStatus;
import org.springframework.web.reactive.function.server.RequestPredicates;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.RouterFunctions;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import org.springframework.web.server.ResponseStatusException;

import com.hm.common.api.ApiResult;
import com.hm.common.api.ApiStatus;

/**
 * 统一异常处理
 * 
 * @author hwg
 *
 *         2020年12月18日
 */
public class JsonExceptionHandler extends DefaultErrorWebExceptionHandler {
	private final static Logger logger = LoggerFactory.getLogger(JsonExceptionHandler.class);

	public JsonExceptionHandler(ErrorAttributes errorAttributes, Resources resources, ErrorProperties errorProperties, ApplicationContext applicationContext) {
		super(errorAttributes, resources, errorProperties, applicationContext);
	}

	/**
	 * 获取异常属性
	 */
	@Override
	protected Map<String, Object> getErrorAttributes(ServerRequest request, ErrorAttributeOptions options) {
		String reqId = request.exchange().getRequest().getId();
		Throwable error = super.getError(request);
		if (error instanceof org.springframework.web.server.ResponseStatusException) {
			ResponseStatusException se = (ResponseStatusException) error;
			if (se.getStatus() == HttpStatus.NOT_FOUND) {
				return ApiResult.of(reqId, ApiStatus.STATUS_404, request.path()).toMap();
			}

			if (se.getStatus() == HttpStatus.BAD_GATEWAY) {
				return ApiResult.of(reqId, ApiStatus.STATUS_503, request.path()).toMap();
			}
		}
		return ApiResult.of(reqId, ApiStatus.STATUS_500, request.path()).toMap();
	}

	/**
	 * 指定响应处理方法为JSON处理的方法
	 * 
	 * @param errorAttributes
	 */
	@Override
	protected RouterFunction<ServerResponse> getRoutingFunction(ErrorAttributes errorAttributes) {
		return RouterFunctions.route(RequestPredicates.all(), this::renderErrorResponse);
	}

	@Override
	protected int getHttpStatus(Map<String, Object> errorAttributes) {
		return (int) errorAttributes.get("status");
	}

}
